package com.xy.utils;

import com.google.gson.Gson;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.json.JSONObject;
import sun.misc.BASE64Encoder;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.validation.constraints.NotBlank;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @BelongsPackage: com.xy.utils
 * @Author: WK
 * @CreateTime: 2023-07-27
 * @Description: 身份证二要素验证
 * @Version: 1.0
 */
@Slf4j
public class IdCarUtils {


	private static final String secretId = "AKID4B6y5HUs71MBBzlIE21o4uyG1SP36ESN95ZS";
	private static final String secretKey = "1y3124OIM18f5zVPCrUKdNJwM1Y8vr4nHgexK81k";

	/**
	 * 二要素
	 * @param name
	 * @param idCar
	 * @return
	 */
	public static Res idCarVerify(@NotBlank String name, @NotBlank String idCar) {
		boolean b = IdCardCheckUtil.checkIdCardProc(idCar);
		if (!b) {
			Res res = new Res();
			res.setCode(400);
			res.setMessage("身份证号码不正确");
			return res;
		}
		// 查询参数
		Map<String, String> queryParams = new HashMap<String, String>();
		queryParams.put("idcard", idCar);
		queryParams.put("name", name);
		String url = "https://service-2n5qa8cl-1256140209.ap-shanghai.apigateway.myqcloud.com/release/eid/check";
		return execute(url, queryParams, "GET");
	}

	/**
	 * 三要素
	 * @param name
	 * @param idCar
	 * @param headUrl
	 * @return
	 */
	public static Res faceIdCard(@NotBlank String name, @NotBlank String idCar, @NotBlank String headUrl) {
		boolean b = IdCardCheckUtil.checkIdCardProc(idCar);
		if (!b) {
			Res res = new Res();
			res.setCode(400);
			res.setMessage("身份证号码不正确");
			return res;
		}
		Map<String, String> queryParams = new HashMap<String, String>();
		queryParams.put("idcard", idCar);
		queryParams.put("name", name);
//		queryParams.put("image", "url");
		queryParams.put("url", headUrl);
		String url = "https://service-ndq49qvj-1256140209.ap-shanghai.apigateway.myqcloud.com/release/face_id_card/post";
		return execute(url,queryParams, "POST");
	}

	public static void main(String[] args) {
		idCarVerify("郭建","610323199307223336");
		faceIdCard("卢其鹏","130125198309105555","https://showface.oss-accelerate.aliyuncs.com/upload/20230903/f0bd1c672307ed2ff35100101f71bd6a.jpg");
	}

	@SneakyThrows
	private static Res execute(String url, Map<String, String> queryParams, String method) {
		String source = "market";
		Calendar cd = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
		sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
		String datetime = sdf.format(cd.getTime());
		// 签名
		String auth = calcAuthorization(source, secretId, secretKey, datetime);
		// 请求方法

		// 请求头
		Map<String, String> headers = new HashMap<String, String>();
		headers.put("X-Source", source);
		headers.put("X-Date", datetime);
		headers.put("Authorization", auth);

		// body参数
		Map<String, String> bodyParams = new HashMap<String, String>();
		// url参数拼接
//		String url = "https://service-2n5qa8cl-1256140209.ap-shanghai.apigateway.myqcloud.com/release/eid/check";
		if (!queryParams.isEmpty() && !"POST".equals(method)) {
			url += "?" + urlencode(queryParams);
		}
		log.info("请求身份证校验接口参数数据:{}", url);
		Res res = new Res();
		BufferedReader in = null;
		try {
			URL realUrl = new URL(url);
			HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
			conn.setConnectTimeout(5000);
			conn.setReadTimeout(5000);
			conn.setRequestMethod(method);
			for (Map.Entry<String, String> entry : headers.entrySet()) {
				conn.setRequestProperty(entry.getKey(), entry.getValue());
			}
			Map<String, Boolean> methods = new HashMap<>();
			methods.put("POST", true);
			methods.put("PUT", true);
			methods.put("PATCH", true);
			Boolean hasBody = methods.get(method);
			if (hasBody != null) {
				conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

				conn.setDoOutput(true);
				DataOutputStream out = new DataOutputStream(conn.getOutputStream());
				out.writeBytes(urlencode(queryParams));
				out.flush();
				out.close();
			}
			if (conn.getResponseCode() == HttpStatus.SC_OK) {
				in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			} else {
				in = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
			}
			String line;
			String result = "";
			while ((line = in.readLine()) != null) {
				result += line;
			}
			JSONObject jsonObject = new JSONObject(result);
			res = new Gson().fromJson(jsonObject.toString(), Res.class);
			log.info("请求身份证校验接口响应数据:{}", jsonObject.toString());

		} catch (Exception e) {

			e.printStackTrace();
		} finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		return res;
	}


	private static String calcAuthorization(String source, String secretId, String secretKey, String datetime)
		throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
		String signStr = "x-date: " + datetime + "\n" + "x-source: " + source;
		Mac mac = Mac.getInstance("HmacSHA1");
		Key sKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), mac.getAlgorithm());
		mac.init(sKey);
		byte[] hash = mac.doFinal(signStr.getBytes("UTF-8"));
		String sig = new BASE64Encoder().encode(hash);

		String auth = "hmac id=\"" + secretId + "\", algorithm=\"hmac-sha1\", headers=\"x-date x-source\", signature=\"" + sig + "\"";
		return auth;
	}

	private static String urlencode(Map<?, ?> map) throws UnsupportedEncodingException {
		StringBuilder sb = new StringBuilder();
		for (Map.Entry<?, ?> entry : map.entrySet()) {
			if (sb.length() > 0) {
				sb.append("&");
			}
			sb.append(String.format("%s=%s",
				URLEncoder.encode(entry.getKey().toString(), "UTF-8"),
				URLEncoder.encode(entry.getValue().toString(), "UTF-8")
			));
		}
		return sb.toString();
	}


	@Data
	@ToString
	public static class Res {
		private int code;
		private CarInfo result;
		private String message;
		private DataInfo data;
	}

	@Data
	public static class CarInfo {
		private String name;
		private String idcard;
		// ，1 一致；2 不一致；3 无记录
		//(1)现役军人、武警官兵、特殊部门人员及特殊级别官员；
		//(2)退役不到2年的军人和士兵（根据军衔、兵种不同，时间会有所不同，一般为2年）；
		//(3)户口迁出，且没有在新的迁入地迁入；
		//(4)户口迁入新迁入地，当地公安系统未将迁移信息上报到公安部（上报时间地域不同而有所差异）；
		//(5)更改姓名，当地公安系统未将更改信息上报到公安部（上报时间因地域不同而有所差异）；
		//(6)移民；
		//(7)未更换二代身份证；
		//(8)死亡。
		//(9)身份证号确实不存在
		private String res;
		private String description;
		private String sex;
		private String birthday;
		private String address;



	}
	@Data
	public static class DataInfo {
		private String msg;
		private int incorrect;
		private float score;



	}

}
